import { SQL } from '#src/database/core/SQL.js';

/**
 * 数据库查询执行器，提供安全的SQL查询执行和事务管理
 */
export class QueryExecutor {
    /**
     * 执行单个SQL查询
     * @param {Object} queryDef - 查询定义对象
     * @param {Object} paramValues - 参数值对象
     * @param {Object} context - 查询上下文
     * @returns {Promise<Object>} 查询结果
     */
    static async execute(queryDef, paramValues, context = {}) {
        this._validateQueryInput(queryDef, paramValues);
        const params = this.buildParams(queryDef.params, paramValues);
        return SQL.query(queryDef.sql, params, context);
    }

    /**
     * 执行事务中的多个查询
     * @param {Array} queries - 查询数组
     * @param {number} timeoutMs - 事务超时时间(毫秒)
     * @returns {Promise<Array>} 每个查询的结果数组
     */
    static async executeTransaction(queries, timeoutMs = 30000) {
        if (!queries || !Array.isArray(queries) || queries.length === 0) {
            throw new Error('事务查询列表不能为空');
        }

        // 创建超时Promise
        const timeoutPromise = new Promise((_, reject) => {
            setTimeout(() => reject(new Error(`事务执行超时(${timeoutMs}ms)`)), timeoutMs);
        });

        // 事务执行Promise
        const transactionPromise = (async () => {
            const connection = await SQL.pool.getConnection();
            try {
                await connection.beginTransaction();
                const results = [];

                for (const { queryDef, paramValues, context } of queries) {
                    this._validateQueryInput(queryDef, paramValues);
                    const params = this.buildParams(queryDef.params, paramValues);
                    // 使用SQL类的查询方法以保持安全验证
                    const result = await SQL.queryWithConnection(connection, queryDef.sql, params, context);
                    results.push(result);
                }

                await connection.commit();
                return results;
            } catch (error) {
                await connection.rollback().catch(rollbackErr => {
                    console.error('事务回滚失败:', rollbackErr);
                });
                throw new Error(`事务执行失败: ${error.message}`);
            } finally {
                connection.release();
            }
        })();

        // 超时控制与事务执行竞争
        return Promise.race([transactionPromise, timeoutPromise]);
    }

    /**
     * 构建查询参数数组
     * @param {Array} paramDefs - 参数定义数组
     * @param {Object} paramValues - 参数值对象
     * @returns {Array} 按顺序排列的参数值数组
     */
    static buildParams(paramDefs, paramValues) {
        return paramDefs.map(param => {
            if (paramValues[param] === undefined) {
                throw new Error(`缺少参数值: ${param}`);
            }
            return paramValues[param];
        });
    }

    /**
     * 验证查询输入
     * @param {Object} queryDef - 查询定义
     * @param {Object} paramValues - 参数值
     */
    static _validateQueryInput(queryDef, paramValues) {
        if (!queryDef || !queryDef.sql || !Array.isArray(queryDef.params)) {
            throw new Error('无效的查询定义格式');
        }

        if (!paramValues || typeof paramValues !== 'object') {
            throw new Error('参数值必须是对象类型');
        }

        // 检查是否存在未定义的参数
        queryDef.params.forEach(param => {
            if (paramValues[param] === undefined) {
                throw new Error(`查询参数${param}未定义`);
            }
        });
    }
}